home *** CD-ROM | disk | FTP | other *** search
/ Cre@te Online 2000 December / Cre@teOnline CD05.iso / MacSoft / XML Instance.sea / XML Instance / Required / plugins / HTMLWindow.jar / horst / TextView.class (.txt) < prev    next >
Encoding:
Java Class File  |  2000-03-18  |  10.2 KB  |  416 lines

  1. package horst;
  2.  
  3. import java.awt.Color;
  4. import java.awt.Font;
  5. import java.awt.FontMetrics;
  6. import java.awt.Graphics;
  7. import java.awt.Rectangle;
  8. import java.awt.Shape;
  9. import java.awt.Toolkit;
  10.  
  11. public class TextView extends View {
  12.    boolean m_bSplittable = true;
  13.    Color m_color;
  14.    int m_maxTokenLength = -1;
  15.    Font m_SubSuperScriptFont;
  16.    char[] debug;
  17.  
  18.    public TextView(View parent, Element e, HTMLPane container) {
  19.       super(parent, e, container);
  20.    }
  21.  
  22.    protected boolean canSplit(int width) {
  23.       if (!this.m_bSplittable) {
  24.          return false;
  25.       } else {
  26.          char[] data = super.m_elem.getCharData();
  27.          FontMetrics fm = ((View)this).getFontMetrics();
  28.          int delim = -1;
  29.          int len = data.length;
  30.          if (len < 2) {
  31.             return false;
  32.          } else {
  33.             int last = -1;
  34.             int currLen = 0;
  35.  
  36.             int i;
  37.             for(i = 0; i < len; ++i) {
  38.                currLen += fm.charWidth(data[i]);
  39.                if (currLen > width) {
  40.                   break;
  41.                }
  42.  
  43.                if (Character.isWhitespace(data[i])) {
  44.                   last = i;
  45.                }
  46.             }
  47.  
  48.             if (i == len) {
  49.                return false;
  50.             } else {
  51.                return last != -1;
  52.             }
  53.          }
  54.       }
  55.    }
  56.  
  57.    protected Color getColor() {
  58.       return ((View)this).isLink() && super.m_elem.getHasFocus() ? super.m_elem.getFocusColor() : this.m_color;
  59.    }
  60.  
  61.    protected int getDescent() {
  62.       return ((View)this).getFontMetrics().getDescent();
  63.    }
  64.  
  65.    protected int getMaximumTokenLength() {
  66.       if (this.m_maxTokenLength > -1) {
  67.          return this.m_maxTokenLength;
  68.       } else {
  69.          this.m_maxTokenLength = 0;
  70.          FontMetrics fm = ((View)this).getFontMetrics();
  71.          char[] data = super.m_elem.getCharData();
  72.          int p1 = data.length;
  73.  
  74.          for(int i = p1 - 1; i >= 0; --i) {
  75.             if (Character.isWhitespace(data[i])) {
  76.                int offset = Math.min(i + 1, data.length);
  77.                if (offset < data.length) {
  78.                   int nChars = p1 - i - 1;
  79.                   int strlen = fm.charsWidth(data, offset, nChars);
  80.                   this.m_maxTokenLength = Math.max(strlen, this.m_maxTokenLength);
  81.                }
  82.  
  83.                p1 = i;
  84.             }
  85.          }
  86.  
  87.          if (p1 == data.length) {
  88.             this.m_maxTokenLength = fm.charsWidth(data, 0, data.length);
  89.          } else if (p1 > 0) {
  90.             this.m_maxTokenLength = Math.max(this.m_maxTokenLength, fm.charsWidth(data, 0, p1));
  91.          }
  92.  
  93.          return this.m_maxTokenLength;
  94.       }
  95.    }
  96.  
  97.    protected int getMinimumSpan(int axis) {
  98.       return this.getPreferredSpan(axis);
  99.    }
  100.  
  101.    protected int getPreferredSpan(int axis) {
  102.       if (axis == 1 && super.m_prefWidth != -1) {
  103.          return super.m_prefWidth;
  104.       } else if (axis == 0 && super.m_prefHeight != -1) {
  105.          return super.m_prefHeight;
  106.       } else if (super.m_elem.m_p0 > super.m_elem.m_p1) {
  107.          System.out.println("Element pointer corruption!!");
  108.          super.m_prefWidth = 0;
  109.          super.m_prefHeight = 0;
  110.          return 0;
  111.       } else {
  112.          FontMetrics fm;
  113.          if (axis != 1 || this.m_SubSuperScriptFont == null || !super.m_elem.isAttributeDefined("superscript") && !super.m_elem.isAttributeDefined("subscript")) {
  114.             fm = ((View)this).getFontMetrics();
  115.          } else {
  116.             fm = Toolkit.getDefaultToolkit().getFontMetrics(this.m_SubSuperScriptFont);
  117.          }
  118.  
  119.          switch (axis) {
  120.             case 0:
  121.                super.m_prefHeight = fm.getAscent();
  122.                return super.m_prefHeight;
  123.             case 1:
  124.                char[] data = super.m_elem.getCharData();
  125.                super.m_prefWidth = fm.charsWidth(data, 0, data.length);
  126.                return super.m_prefWidth;
  127.             default:
  128.                return 0;
  129.          }
  130.       }
  131.    }
  132.  
  133.    protected void init() {
  134.       ((View)this).setInsets(0, 0, 0, 0);
  135.       this.m_color = Utilities.setColorProperty(super.m_elem.getDocument().getTextColor(), "textcolor", super.m_elem.getAttributes());
  136.       if (super.m_elem.isAttributeDefined("superscript") || super.m_elem.isAttributeDefined("subscript")) {
  137.          this.m_SubSuperScriptFont = TextAttributes.createFont(((View)this).getFont(), "-2");
  138.       }
  139.  
  140.       this.debug = super.m_elem.getCharData();
  141.    }
  142.  
  143.    protected boolean isContainerView() {
  144.       return false;
  145.    }
  146.  
  147.    protected boolean isSplittable() {
  148.       return true;
  149.    }
  150.  
  151.    protected boolean isUnderlined() {
  152.       boolean bLink = ((View)this).isLink();
  153.       if (bLink && super.m_elem.m_relatedElements.size() == 0 && Utilities.isBlank(super.m_elem.getCharData())) {
  154.          return false;
  155.       } else if (bLink) {
  156.          return super.m_container.m_props.m_bUnderLineLinks;
  157.       } else {
  158.          boolean bUnderLine = false;
  159.          String src = (String)super.m_elem.getAttribute("underline");
  160.          if (src != null) {
  161.             bUnderLine = src.equals("true");
  162.          }
  163.  
  164.          return bUnderLine;
  165.       }
  166.    }
  167.  
  168.    protected Rectangle layout(int x, int y, int width, LayoutInfo info) {
  169.       width = this.getPreferredSpan(1);
  170.       super.m_bounds = new Rectangle(x, y, width, this.getPreferredSpan(0));
  171.       return super.m_bounds;
  172.    }
  173.  
  174.    public void paint(Graphics g, Shape alloc) {
  175.       Rectangle clip = alloc.getBounds();
  176.       char[] data = super.m_elem.getCharData();
  177.       if (super.m_bounds.intersects(clip) && data != null && data.length > 0) {
  178.          Font oldFont = g.getFont();
  179.          Color oldColor = g.getColor();
  180.          Font f = ((View)this).getFont();
  181.          g.setFont(f);
  182.          FontMetrics fm = g.getFontMetrics();
  183.          if (super.m_container.isTextSelected()) {
  184.             int start = super.m_container.m_document.m_selectedP0;
  185.             int end = super.m_container.m_document.m_selectedP1;
  186.             if (start > end) {
  187.                int save = start;
  188.                start = end;
  189.                end = save;
  190.             }
  191.  
  192.             boolean bSelection = true;
  193.             int xStart = 0;
  194.             int xEnd = 0;
  195.             if (super.m_elem.m_p0 <= start && super.m_elem.m_p1 >= start && super.m_elem.m_p1 <= end) {
  196.                xStart = start;
  197.                xEnd = super.m_elem.m_p1;
  198.             } else if (super.m_elem.m_p0 >= start && super.m_elem.m_p1 <= end) {
  199.                xStart = super.m_elem.m_p0;
  200.                xEnd = super.m_elem.m_p1;
  201.             } else if (super.m_elem.m_p0 >= start && super.m_elem.m_p0 <= end && super.m_elem.m_p1 >= end) {
  202.                xStart = super.m_elem.m_p0;
  203.                xEnd = end;
  204.             } else if (super.m_elem.m_p0 <= start && super.m_elem.m_p1 >= end) {
  205.                xStart = start;
  206.                xEnd = end;
  207.             } else {
  208.                bSelection = false;
  209.             }
  210.  
  211.             if (bSelection) {
  212.                int len = xEnd - xStart + 1;
  213.                char[] chardata = new char[len];
  214.                StringBuffer buffer = ((View)this).getDocument().getTextBuffer();
  215.                int buflen = buffer.length();
  216.                int i = 0;
  217.  
  218.                for(int j = xStart; i < len && j < buflen; ++j) {
  219.                   chardata[i] = buffer.charAt(j);
  220.                   ++i;
  221.                }
  222.  
  223.                int strWidth = fm.charsWidth(chardata, 0, chardata.length);
  224.                int offset = 0;
  225.                if (xStart > super.m_elem.m_p0) {
  226.                   int slen = xStart - super.m_elem.m_p0;
  227.                   char[] cdata = new char[slen];
  228.                   int i = 0;
  229.  
  230.                   for(int j = super.m_elem.m_p0; i < slen; ++j) {
  231.                      cdata[i] = buffer.charAt(j);
  232.                      ++i;
  233.                   }
  234.  
  235.                   offset = fm.stringWidth(new String(cdata));
  236.                }
  237.  
  238.                g.setColor(Color.cyan);
  239.                g.fillRect(super.m_bounds.x + offset, super.m_bounds.y, strWidth, super.m_bounds.height + this.getDescent());
  240.             }
  241.          }
  242.  
  243.          g.setColor(this.getColor());
  244.          if (super.m_elem.isAttributeDefined("superscript") && this.m_SubSuperScriptFont != null) {
  245.             g.setFont(this.m_SubSuperScriptFont);
  246.             FontMetrics fmetrics = g.getFontMetrics();
  247.             fmetrics = g.getFontMetrics();
  248.             g.drawChars(data, 0, data.length, super.m_bounds.x, super.m_bounds.y + fmetrics.getAscent() - fmetrics.getLeading() - fm.getDescent());
  249.          } else if (super.m_elem.isAttributeDefined("subscript") && this.m_SubSuperScriptFont != null) {
  250.             g.setFont(this.m_SubSuperScriptFont);
  251.             FontMetrics fmetrics = g.getFontMetrics();
  252.             g.drawChars(data, 0, data.length, super.m_bounds.x, super.m_bounds.y + super.m_bounds.height + this.getDescent());
  253.          } else {
  254.             g.drawChars(data, 0, data.length, super.m_bounds.x, super.m_bounds.y + super.m_bounds.height);
  255.          }
  256.  
  257.          if (this.isUnderlined()) {
  258.             int y = super.m_bounds.y + super.m_bounds.height + this.getDescent() / 2;
  259.             g.drawLine(super.m_bounds.x, y, super.m_bounds.x + fm.charsWidth(data, 0, data.length), y);
  260.          }
  261.  
  262.          ((View)this).drawDebugBox(g, Color.black);
  263.          g.setFont(oldFont);
  264.          g.setColor(oldColor);
  265.       }
  266.  
  267.    }
  268.  
  269.    protected void reset() {
  270.       super.m_elem.reset();
  271.       this.m_maxTokenLength = -1;
  272.    }
  273.  
  274.    protected void setCanWrap(boolean bSplittable) {
  275.       this.m_bSplittable = bSplittable;
  276.    }
  277.  
  278.    protected boolean setToLineStarter() {
  279.       if (super.m_elem.m_bInPreformat) {
  280.          return true;
  281.       } else {
  282.          char[] data = super.m_elem.getCharData();
  283.          boolean isBlank = true;
  284.          int i = 0;
  285.  
  286.          int trimPos;
  287.          for(trimPos = -1; i < data.length; trimPos = i) {
  288.             if (!Character.isWhitespace(data[i++])) {
  289.                isBlank = false;
  290.                break;
  291.             }
  292.          }
  293.  
  294.          if (isBlank) {
  295.             return false;
  296.          } else {
  297.             if (trimPos >= 0) {
  298.                Element var10000 = super.m_elem;
  299.                var10000.m_p0 += trimPos;
  300.             }
  301.  
  302.             return super.m_elem.m_p0 <= super.m_elem.m_p1;
  303.          }
  304.       }
  305.    }
  306.  
  307.    protected View[] split(int width) {
  308.       char[] data = super.m_elem.getCharData();
  309.       FontMetrics fm = ((View)this).getFontMetrics();
  310.       int lastWhiteSpace = -1;
  311.       int currentLen = 0;
  312.       int len = data.length;
  313.       int delim = -1;
  314.       int lenminus1 = len - 1;
  315.  
  316.       for(int i = 0; i < len; ++i) {
  317.          currentLen += fm.charWidth(data[i]);
  318.          if (currentLen > width && delim > -1) {
  319.             break;
  320.          }
  321.  
  322.          if (Character.isWhitespace(data[i])) {
  323.             delim = i;
  324.          }
  325.       }
  326.  
  327.       int lastPos = delim == -1 ? Math.max(0, len - 1) : delim;
  328.       Element e1 = new Element(super.m_elem);
  329.       e1.m_p0 = super.m_elem.m_p0;
  330.       e1.m_p1 = e1.m_p0 + lastPos;
  331.       e1.m_anchor = super.m_elem.m_anchor;
  332.       boolean bIsLink = super.m_elem.isLink();
  333.       if (bIsLink) {
  334.          Element[] relatedElems = super.m_elem.getRelatedElements();
  335.  
  336.          for(int j = 0; j < relatedElems.length; ++j) {
  337.             e1.addRelatedElement(relatedElems[j]);
  338.          }
  339.       }
  340.  
  341.       View v1 = super.m_container.m_viewFactory.createView((View)null, e1, super.m_container);
  342.       if (e1.m_p1 != super.m_elem.m_p1 && delim != -1) {
  343.          Element e2 = new Element(super.m_elem);
  344.          e2.m_p0 = Math.min(super.m_elem.m_p1, e1.m_p1 + 1);
  345.          e2.m_p1 = super.m_elem.m_p1;
  346.          e2.m_anchor = super.m_elem.m_anchor;
  347.          if (bIsLink) {
  348.             Element[] relatedElems = super.m_elem.getRelatedElements();
  349.  
  350.             for(int j = 0; j < relatedElems.length; ++j) {
  351.                e2.addRelatedElement(relatedElems[j]);
  352.             }
  353.          }
  354.  
  355.          View v2 = super.m_container.m_viewFactory.createView((View)null, e2, super.m_container);
  356.          Element[] relates = super.m_elem.getRelatedElements();
  357.  
  358.          for(int j = 0; j < relates.length; ++j) {
  359.             relates[j].addRelatedElement(e1);
  360.             relates[j].addRelatedElement(e2);
  361.          }
  362.  
  363.          e1.addRelatedElement(e2);
  364.          e2.addRelatedElement(e1);
  365.          if (super.m_elem.m_anchor != null) {
  366.             Element[] newElems = new Element[]{e1, e2};
  367.             super.m_elem.m_anchor.replaceRelatedElement(super.m_elem, newElems);
  368.          }
  369.  
  370.          View[] vws = new View[2];
  371.          vws[0] = v1;
  372.          vws[1] = v2;
  373.          return vws;
  374.       } else {
  375.          if (super.m_elem.m_anchor != null) {
  376.             Element[] newElems = new Element[1];
  377.             newElems[0] = e1;
  378.             super.m_elem.m_anchor.replaceRelatedElement(super.m_elem, newElems);
  379.          }
  380.  
  381.          View[] vws = new View[2];
  382.          vws[0] = v1;
  383.          vws[1] = null;
  384.          return vws;
  385.       }
  386.    }
  387.  
  388.    protected ElementViewInfo viewToModel(int x, int y) {
  389.       ElementViewInfo info = null;
  390.       Rectangle bounds = ((View)this).getBounds();
  391.       if (bounds.contains(x, y)) {
  392.          FontMetrics fm = ((View)this).getFontMetrics();
  393.          char[] pcdata = super.m_elem.getCharData();
  394.          int strWidth = 0;
  395.          if (pcdata.length > 0) {
  396.             int nChars;
  397.             int charWidth;
  398.             for(nChars = 0; nChars < pcdata.length && bounds.x + strWidth <= x; strWidth += charWidth) {
  399.                charWidth = fm.charWidth(pcdata[nChars++]);
  400.             }
  401.  
  402.             new String(pcdata, 0, nChars);
  403.             super.m_elem.m_textbufferPosition = super.m_elem.m_p0;
  404.             if (nChars > 0) {
  405.                Element var10000 = super.m_elem;
  406.                var10000.m_textbufferPosition += nChars - 1;
  407.             }
  408.          }
  409.  
  410.          info = new ElementViewInfo(super.m_elem, this);
  411.       }
  412.  
  413.       return info;
  414.    }
  415. }
  416.